#pragma once

#include <iostream>
#include <pthread.h>
#include <string>
#include <functional>
#include <cassert>


// 前向声明
class Thread;


//上下文
class Context
{
public:
    Thread *this_;
    void *args_;
public:
    Context():this_(nullptr),args_(nullptr)
    {}

    ~Context()
    {}
};



class Thread
{
public:
    typedef std::function<void*(void*)> func_t;
    const int num = 1024;

public:
    Thread(func_t func,void *args,int number) : func_(func)
    {
        char buffer[num];
        snprintf(buffer,sizeof buffer,"thread-%d",number);
        name_ = buffer;
        args_ = args;
        


        Context *ctx = new Context();
        ctx->this_ = this;
        ctx->args_ = args_;

        int n = pthread_create(&tid_,nullptr,start_routine,ctx);
        assert(n == 0);
        (void)n;
    }

    // 在类内创建线程，想让线程执行对应的方法，需要将方法设置成为static
    static void *start_routine(void *args)
    {   
        Context *ctx = static_cast<Context *>(args);
        void *ret = ctx->this_->run(ctx->args_);
        delete ctx;
        return ret;

        //静态方法不能调用成员方法，只能调用静态成员方法
        //return func_(args);
    }



    void join()
    {
        int n = pthread_join(tid_,nullptr);
        assert(n == 0);
        (void)n;
    }


    void *run(void *args)
    {
        return func_(args);
    }

    ~Thread()
    {
        //do nothing
    }



private:
    std::string name_;
    func_t func_;
    void *args_;
    pthread_t tid_;
};


